/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.gen.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.thinkgem.jeesite.common.persistence.BaseConstants;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.frame.pm.utils.PmParamUtils;
import com.thinkgem.jeesite.modules.gen.GenConstants;
import com.thinkgem.jeesite.modules.gen.dao.GenTableMapper;
import com.thinkgem.jeesite.modules.gen.entity.GenProject;
import com.thinkgem.jeesite.modules.gen.entity.GenTable;
import com.thinkgem.jeesite.modules.gen.entity.GenTableColumn;
import com.thinkgem.jeesite.modules.gen.util.GenUtils;
import com.thinkgem.jeesite.modules.gen.util.ModelUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * 代码生成-表信息Service
 *
 * @author kongxiangsheng
 * @version 2018-08-16
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class GenTableService extends ServiceImpl<GenTableMapper, GenTable> implements IService<GenTable> {
    @Autowired
    private GenTableColumnService genTableColumnService;

    /**
     * 根据id获取（含列信息）
     *
     * @param id
     * @return
     */
    public GenTable getWithColumns(String id) {
        GenTable genTable = this.getById(id);
        genTable.setColumnList(genTableColumnService.getByGenTableId(id));
        return genTable;
    }

    /**
     * 获取用于生成代码的table对象信息
     *
     * @param id
     * @return
     */
    public GenTable getForGenerate(String id, List<String> baseColumns, List<String> baseTreeColumns, GenProject genProject) {
        // 正常获取含列信息
        GenTable genTable = this.getWithColumns(id);

        // 获取子表及其列信息
        QueryWrapper queryWrapper = new QueryWrapper<GenTable>();
        queryWrapper.eq(GenTable.COL_PARENT_TABLE, genTable.getName());
        List<GenTable> childTableList = this.baseMapper.selectList(queryWrapper);
        for (GenTable childTable : childTableList) {
            // 备注
            if (StringUtils.isBlank(childTable.getComments())) {
                childTable.setComments(childTable.getName());
            }
            // 获取表名的简写名称
            childTable.setShortName(GenUtils.genTableShortName(childTable.getName(), genProject.getTablePrefix()));
            // 获取类名（驼峰&首字母小写）
            String classNameCapital = GenUtils.genClassNameCapital(childTable.getName(), genProject.getTablePrefix());
            childTable.setClassNameCapital(classNameCapital);
            childTable.setClassNameUnCapital(StringUtils.uncapitalize(childTable.getClassNameCapital()));
            // 外键
            childTable.setParentTableFkLower(StringUtils.lowerCase(childTable.getParentTableFk()));
            childTable.setParentTableFkUpper(StringUtils.upperCase(childTable.getParentTableFk()));
            childTable.setParentTableFKJavaNameCapital(StringUtils.toCapitalizeCamelCase(childTable.getParentTableFk()));
            childTable.setParentTableFKJavaNameUnCapital(StringUtils.toCamelCase(childTable.getParentTableFk()));

            // 子表列信息
            childTable.setColumnList(genTableColumnService.getForGenerate(childTable, baseColumns, baseTreeColumns));
        }
        genTable.setChildTableList(childTableList);
        genTable.setHaveChildTable(CollectionUtils.isEmpty(genTable.getChildTableList()) ? "false" : "true");

        // 备注
        if (StringUtils.isBlank(genTable.getComments())) {
            genTable.setComments(genTable.getName());
        }

        // 获取表名简写
        genTable.setShortName(GenUtils.genTableShortName(genTable.getName(), genProject.getTablePrefix()));

        // 获取类名（驼峰&首字母小写）
        String classNameCapital = GenUtils.genClassNameCapital(genTable.getName(), genProject.getTablePrefix());
        genTable.setClassNameCapital(classNameCapital);
        genTable.setClassNameUnCapital(StringUtils.uncapitalize(genTable.getClassNameCapital()));
        // 是否含有父表
        genTable.setHaveParentTable(StringUtils.isBlank(genTable.getParentTable()) ? "false" : "true");
        // 主键List
        genTable.setPkList(getPkList(genTable.getColumnList()));
        // 是否含有主键
        genTable.setHavePk(CollectionUtils.isEmpty(genTable.getPkList()) ? "false" : "true");
        // entity文件的依赖包
        genTable.setEntityImportList(ModelUtils.getEntityImportList(genTable, baseColumns));
        // service文件的依赖包
        genTable.setServiceImportList(ModelUtils.getServiceImportList(genTable));

        // 字段名&备注
        genTable.setNameAndComments(genTable.getName() + " : " + genTable.getComments());

        // 列信息
        genTable.setColumnList(genTableColumnService.getForGenerate(genTable, baseColumns, baseTreeColumns));

        // 表外键
        String parentTableFk = genTable.getParentTableFk();
        genTable.setParentTableFkLower(StringUtils.lowerCase(parentTableFk));
        genTable.setParentTableFkUpper(StringUtils.upperCase(parentTableFk));
        genTable.setParentTableFKJavaNameCapital(StringUtils.toCapitalizeCamelCase(genTable.getParentTableFk()));
        genTable.setParentTableFKJavaNameUnCapital(StringUtils.toCamelCase(genTable.getParentTableFk()));

        return genTable;
    }

    /**
     * 保存数据（含列信息）
     *
     * @param genTable
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveWithChildren(GenTable genTable) {
        this.saveOrUpdate(genTable);

        for (GenTableColumn genTableColumn : genTable.getColumnList()) {
            if (BaseConstants.DEL_FLAG_DELETE.equals(genTableColumn.getDelFlag())) {
                genTableColumnService.removeById(genTableColumn.getId());
            } else {
                // TODO: 有没有办法不用加下面这行
                genTableColumn.setGenTableId(genTable.getId());
                genTableColumnService.saveOrUpdate(genTableColumn);
            }
        }
    }

    /**
     * 删除数据（含子表数据）
     *
     * @param genTable
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteWithChildren(GenTable genTable) {
        this.removeById(genTable.getId());
        genTableColumnService.deleteByGenTableId(genTable.getId());
    }

    /**
     * 获取物理数据表列表
     *
     * @param genTable
     * @return
     */
    public List<GenTable> findTableListFormDb(GenTable genTable) {
        // 打开数据库连接
        SqlSessionFactory sqlSessionFactory = GenUtils.getSqlSessionFactory();
        SqlSession sqlSession = SqlSessionUtils.getSqlSession(sqlSessionFactory);

        // 查询数据
        GenTableMapper genTableMapper = sqlSession.getMapper(GenTableMapper.class);
        List<GenTable> returnList = genTableMapper.findTableList(genTable);

        // 关闭数据库连接
        SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);

        return returnList;
    }

    /**
     * 验证表名是否可用，如果已存在，则返回false
     *
     * @param tableName
     * @return
     */
    public boolean checkTableName(String tableName) {
        if (StringUtils.isBlank(tableName)) {
            return true;
        }
        QueryWrapper queryWrapper = new QueryWrapper<GenTable>();
        queryWrapper.eq(GenTable.COL_NAME, tableName);
        List<GenTable> list = this.baseMapper.selectList(queryWrapper);
        return list.size() == 0;
    }

    public List<GenTable> getAllTableDict() {
        QueryWrapper queryWrapper = new QueryWrapper<GenTable>();
        queryWrapper.select(GenTable.COL_ID, GenTable.COL_COMMENTS, GenTable.COL_NAME, "concat(name,' : ', comments) as nameAndComments");
        queryWrapper.orderByAsc(GenTable.COL_NAME);
        return this.list(queryWrapper);
    }

    /**
     * 获取物理数据表列表
     *
     * @param genTable
     * @return
     */
    public GenTable getTableFormDb(GenTable genTable) {
        // 打开数据库连接
        SqlSessionFactory sqlSessionFactory = GenUtils.getSqlSessionFactory();
        SqlSession sqlSession = SqlSessionUtils.getSqlSession(sqlSessionFactory);

        // 查询数据
        GenTableMapper genTableMapper = sqlSession.getMapper(GenTableMapper.class);

        // 如果表名为空，则直接返回即可
        if (StringUtils.isBlank(genTable.getName())) {
            return genTable;
        }

        // 如果有名字，但是数据库中根本就没有这个表，也直接返回
        List<GenTable> list = genTableMapper.findTableList(genTable);
        if (CollectionUtils.isEmpty(list)) {
            return genTable;
        }

        // 如果是新增，初始化表属性
        if (StringUtils.isBlank(genTable.getId())) {
            genTable = list.get(0);
            // 设置字段说明
            if (StringUtils.isBlank(genTable.getComments())) {
                genTable.setComments(genTable.getName());
            }
        }

        // 添加新列
        List<GenTableColumn> columnList = genTableMapper.findTableColumnList(genTable);
        for (GenTableColumn column : columnList) {
            boolean b = false;
            for (GenTableColumn e : genTable.getColumnList()) {
                if (e.getName().equals(column.getName())) {
                    b = true;
                }
            }
            if (!b) {
                genTable.getColumnList().add(column);
            }
        }

        // 删除已删除的列
        for (GenTableColumn e : genTable.getColumnList()) {
            boolean b = false;
            for (GenTableColumn column : columnList) {
                if (column.getName().equals(e.getName())) {
                    b = true;
                }
            }
            if (!b) {
                e.setDelFlag(GenTableColumn.DEL_FLAG_DELETE);
            }
        }

        // 获取主键
        genTable.setPkList(genTableMapper.findTablePK(genTable));

        // 初始化列属性字段
        GenUtils.initColumnField(genTable);

        // 关闭数据库连接
        SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);

        return genTable;
    }

    /**
     * 获取所有主键
     *
     * @param columns
     * @return
     */
    private List<String> getPkList(List<GenTableColumn> columns) {
        List<String> pkList = Lists.newArrayList();
        for (GenTableColumn column : columns) {
            if ("1".equalsIgnoreCase(column.getIsPk())) {
                pkList.add(column.getName());
            }
        }
        return pkList;
    }

}